package com.zeratul.common.event.config;

import cn.hutool.core.annotation.AnnotationUtil;
import com.zeratul.common.core.utils.spring.SpringUtils;
import com.zeratul.common.event.base.BasePublishServer;
import com.zeratul.common.event.base.BaseSubscribeServer;
import com.zeratul.common.event.base.serial.BaseEventSerialization;
import com.zeratul.common.event.config.prop.ZeratulEventProperties;
import com.zeratul.common.event.core.apply.subscribe.IZtEventHandler;
import com.zeratul.common.event.core.apply.subscribe.ZtEventListener;
import com.zeratul.common.event.core.handler.local.config.SpringEventHandlerAutoConfiguration;
import com.zeratul.common.event.core.handler.redis.config.RedisEventAutoConfiguration;
import com.zeratul.common.event.core.server.publish.StandardPublishServer;
import com.zeratul.common.event.core.server.subscribe.StandardSubscribeServer;
import com.zeratul.common.event.serial.SimpleEventSerialization;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@AutoConfiguration
@ImportAutoConfiguration({EventThreadPoolConfig.class,
        RedisEventAutoConfiguration.class,
        SpringEventHandlerAutoConfiguration.class})
@Import(ZeratulEventProperties.class)
@Slf4j
public class ZeratulEventAutoConfiguration {

    /**
     * 服务层发布者
     */
    @Bean
    @ConditionalOnMissingBean
    public BasePublishServer getStandardPublishServer(){
        return new StandardPublishServer();
    }

    /**
     * 服务层订阅者
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(IZtEventHandler.class)
    public BaseSubscribeServer getStandardSubscribeServer(){
        return new StandardSubscribeServer();
    }

    /**
     * 事件序列化器
     */
    @Bean
    @ConditionalOnMissingBean
    public BaseEventSerialization getSimpleEventSerialization(){
        return new SimpleEventSerialization();
    }

    /**
     * 动态获取当前服务监听的Topic
     */
    @SuppressWarnings("rawtypes")
    @Bean
    @ConditionalOnBean(IZtEventHandler.class)
    public List<String> getTopics(){

        //获取所有的IZtEventHandler接口
        Map<String, IZtEventHandler> ztEventHandlerMap = SpringUtils.getBeansOfType(IZtEventHandler.class);

        //获取所有IZtEventHandler接口上的注解订阅的Topic
        List<String> topics = ztEventHandlerMap.values().stream()
                .filter(ztEventHandler -> AnnotationUtil.hasAnnotation(ztEventHandler.getClass(), ZtEventListener.class))
                .map(ztEventHandler -> AnnotationUtil.getAnnotation(ztEventHandler.getClass(), ZtEventListener.class))
                .map(ZtEventListener::value)
                .flatMap(Arrays::stream)
                .toList();
        log.debug("【事件总线】当前服务订阅的Topic列表为：{}", topics);
        return topics;
    }

}
